package cloud.xlh.bigdatahandle.service.impl;

import cloud.xlh.bigdatahandle.service.AsyncService;
import cloud.xlh.bigdatahandle.utils.JDBCBatchHandleUtil;
import cloud.xlh.bigdatahandle.utils.MmpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/1/3 11:02
 * @ Description:
 */
@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService {
    @Override
    @Async("asyncServiceExecutor")
    public void executeAsync(List<?> logOutputResults, CountDownLatch countDownLatch, Object... args) {
        try {
            log.warn("start executeAsync");
            /**
             * 异步线程要做的事情，可配合JDBC批处理
             * */
            //分批读取+内存映射+JDBC批量处理
            MmpUtil.bigDataRead(null , 0);
            JDBCBatchHandleUtil.insertBigData("");
            log.warn("end executeAsync");
        } finally {
            /**
             * 很关键, 无论上面程序是否异常必须执行countDown,否则await无法释放
             * */
            countDownLatch.countDown();
        }
    }

    public static Byte bigDataRead(String filePath) {
        RandomAccessFile raf = null;
        FileChannel rafchannel = null;
        MappedByteBuffer map = null;
        try {
            raf = new RandomAccessFile(filePath, "rw");
            rafchannel = raf.getChannel();
            //mmap  堆外  和文件映射的   byte  not  objtect
            map = rafchannel.map(FileChannel.MapMode.READ_ONLY, 0, rafchannel.size());
            // 将缓冲区的内容读入ByteBuffer
            ByteBuffer buffer = ByteBuffer.allocate(map.limit());
            buffer.put(map);
            buffer.flip();
            // 打印文件内容
            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
            long position = rafchannel.position();
            return map.get();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rafchannel != null) {
                    rafchannel.close();
                }
                if (raf != null) {
                    raf.close();
                }
            } catch (Exception e) {
                throw new RuntimeException("随机文件对象和channel对象关闭失败");
            }
        }
        return null;
    }

    public static void main(String[] args) {
        Byte aByte = bigDataRead("D:\\资料\\资源\\后端\\技术文档\\[Java程序员修炼之道].(英)埃文斯&(荷)费尔堡著.扫描版(jb51.net).pdf");
        System.out.println(aByte.byteValue());
    }
}
